﻿using System;
using Caliburn.Micro;
using System.ComponentModel;
using System.Linq;
using NHibernate;
using TimeKeeper.Entities;
using TimeKeeper.Events;
using TimeKeeper.Infrastructure;

namespace TimeKeeper.ViewModels
{
    public class ProjectEditViewModel : Screen
    {
        public override string DisplayName { get { return "Edit Project Details"; } set { } }

        private Project _project;
        public Project Project
        {
            get { return _project; }
            set { _project = ViewModelHelper.SetValueWithRegistration(value, _project, WhenProjectChanged); }
        }

        private void WhenProjectChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            NotifyOfPropertyChange(() => CanOk);
        }

        private readonly IEventAggregator _eventAggregator;
        private readonly ISession _session;
        private readonly IEntityFactory _entityFactory;
        private ChangeType _changeType;

        public ProjectEditViewModel(IEventAggregator eventAggregator, ISession session, IEntityFactory entityFactory)
        {
            _session = session;
            _entityFactory = entityFactory;
            _eventAggregator = eventAggregator;
            Project = _entityFactory.Create<Project>();
            _changeType = ChangeType.Added;

        }

        public ProjectEditViewModel WithProject(int projectId)
        {
            _session.QueryInTransaction<Project>(projects => Project = projects.First(project => project.Id == projectId));
            _changeType = ChangeType.Modifed;
            return this;
        }

        public bool CanOk { get { return ViewModelHelper.IsValid(Project); } }

        public void Ok()
        {
            _session.DoInTransaction(session => session.Save(Project));
            _eventAggregator.Publish(new ProjectChanged(Project.Id, _changeType));
            TryClose(true);
        }

        public void Cancel()
        {
            TryClose(false);
        }
    }
}